home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / wais / ui / config.c next >
C/C++ Source or Header  |  1995-05-09  |  12KB  |  481 lines

  1. /* ********************************************************************** *\
  2.  *         Copyright IBM Corporation 1988,1991 - All Rights Reserved      *
  3. ############################################################################
  4. #        Copyright IBM Corporation 1988, 1991 - All Rights Reserved        #
  5. #                                                                          #
  6. # Permission to use, copy, modify, and distribute this software and its    #
  7. # documentation for any purpose and without fee is hereby granted,         #
  8. # provided that the above copyright notice appear in all copies and        #
  9. # that both that copyright notice and this permission notice appear in     #
  10. # supporting documentation, and that the name of IBM not be used in        #
  11. # advertising or publicity pertaining to distribution of the software      #
  12. # without specific, written prior permission.                              #
  13. #                                                                          #
  14. # IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL #
  15. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM #
  16. # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY      #
  17. # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER  #
  18. # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING   #
  19. # OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.    #
  20. ############################################################################
  21. \* ********************************************************************** */
  22. /* $Header: /afs/andrew.cmu.edu/itc/sm/releases/X.V11R5/ftp/src/overhead/util/lib/RCS/config.c,v 2.17 1991/09/12 17:24:52 bobg Exp $ */
  23. /* $ACIS:config.c 1.2$ */
  24. /* $Source: /afs/andrew.cmu.edu/itc/sm/releases/X.V11R5/ftp/src/overhead/util/lib/RCS/config.c,v $ */
  25.  
  26. #ifndef lint
  27. static char *rcsid = "$Header: /afs/andrew.cmu.edu/itc/sm/releases/X.V11R5/ftp/src/overhead/util/lib/RCS/config.c,v 2.17 1991/09/12 17:24:52 bobg Exp $";
  28. #endif /* lint */
  29.  
  30. #include <stdio.h>
  31. #include <ctype.h>
  32. #include <errno.h>
  33.  
  34. #include "config.h"
  35.  
  36. char ProgramName[100];
  37. extern int errno;
  38.  
  39. #define MAXCONFIGSIZE 2000
  40.  
  41. char *conf_ConfigNames[] =  {
  42.     "/AndrewSetup",
  43.     "/etc/AndrewSetup",
  44. #ifdef LOCAL_ANDREW_SETUP_ENV
  45.     LOCAL_ANDREW_SETUP_ENV ,
  46. #endif /* LOCAL_ANDREW_SETUP_ENV */
  47.     "/usr/vice/etc/AndrewSetup",
  48. /* Include a name based on DEFAULT_ANDREWDIR_ENV */
  49. /*    QUOTED_DEFAULT_ANDREWDIR_ANDREWSETUP,*/
  50.     "/usr/andrew/etc/AndrewSetup",
  51.     NULL
  52. };
  53. int conf_ConfigUsed = -1;
  54. int conf_ConfigErrno = -1;
  55.  
  56. /* 
  57.  
  58. getconfiguration -- read information from configuration file /AndrewSetup.
  59.  
  60. */
  61.  
  62.  
  63. ReadConfigureLine(fp, text, maxTextLength, program, programLength, key, keyLength, value, valueLength, condition, conditionLength)
  64. FILE *fp;
  65. char *text;
  66. int maxTextLength;
  67. char **program;
  68. int *programLength;
  69. char **key;
  70. int *keyLength;
  71. char **value;
  72. int *valueLength;
  73. char **condition;
  74. int *conditionLength;
  75. {
  76.     char *keybeg;
  77.     char *keyend;
  78.     char *valpos;
  79.     char *valend;
  80.     char *programBeg;
  81.     char *programEnd;
  82.     static char *thisHost = NULL;
  83.  
  84.     if ((fgets(text, maxTextLength, fp)) != NULL) {
  85.     if (text[0] == '#' || text[0] == '!')  {
  86.         return CONFIG_COMMENT;
  87.     }
  88.     if (text[0] == '?')  {
  89.         int matchIt;
  90.  
  91.         /* Check for Machine Type / Host Name/ Environment variable  */
  92.  
  93.         if (text[1] == 'C' || text[1] == 'M' || text[1] == 'E')  {
  94.         register char *p;
  95.         register char *d;
  96.  
  97.         p = &(text[2]);
  98.  
  99.         /* Test for which comparison */
  100.  
  101.         if (*p == '=')  {
  102.             matchIt = 1;
  103.         } else if (*p == '!')  {
  104.             matchIt = 0;
  105.         } else  {
  106.             return CONFIG_BADENTRY;
  107.         }
  108.  
  109.         /* Get token */
  110.  
  111.         p++;
  112.         while (isspace(*p))  {
  113.             p++;
  114.         }
  115.         d = p;
  116.         while (*p && *p != ':')  {
  117.             if (*p == '\\' && *(p+1)) {
  118.              char *p2;
  119.              for (p2 = p; *p2; ++p2) {
  120.                  *p2 = *(p2+1);
  121.              }
  122.              }
  123.             p++;
  124.         }
  125.  
  126.         keybeg = p + 1;
  127.  
  128.         if (p == d)  {
  129.             return CONFIG_BADENTRY;
  130.         }
  131.  
  132.         p--;
  133.  
  134.         while (p != d && isspace(*p))  {
  135.             p--;
  136.         }
  137.  
  138.         if (condition != NULL && conditionLength != NULL)  {
  139.         *condition = d;
  140.         *conditionLength = p - d + 1;
  141.         }
  142.  
  143.         /* Do proper comparison */
  144.  
  145.         if (text[1] == 'C')  {
  146.             int eq = FoldedEQn(d, SYS_NAME, p-d+1);
  147.             int eq2 = FoldedEQn(d, OPSYSNAME, p-d+1);
  148.  
  149.             if ((!matchIt || ! eq) && (matchIt || eq) && (!matchIt || ! eq2) && (matchIt ||  eq2))  {
  150.             return CONFIG_FALSECONDITION;
  151.              }
  152.          } else if (text[1] == 'E') {
  153.              char *val, *envar, *enval;
  154.              int eq;
  155.  
  156.              val = (char *) index(d, '=');
  157.              if (!val) return CONFIG_BADENTRY;
  158.              envar = (char *) malloc(val - d + 1);
  159.              if (!envar) return CONFIG_BADENTRY;
  160.              strncpy(envar, d, val - d + 1);
  161.              envar[val-d] = '\0';
  162.              enval = (char *) getenv(envar);
  163.              if (!enval) {
  164.              if (matchIt) return CONFIG_FALSECONDITION;
  165.              } else {
  166.              ++val;
  167.              eq = FoldedEQn(val, enval, keybeg - val -1);
  168.              if ((matchIt && !eq) || (!matchIt && eq)) return CONFIG_FALSECONDITION;
  169.             }
  170.         } else {
  171.             if (thisHost == NULL)  {
  172.             thisHost = (char *) malloc(256);
  173.             if (thisHost != NULL) GetHostDomainName(thisHost, 256);
  174.             }
  175.  
  176.             if (thisHost == NULL || (!matchIt || !FoldedEQn(d, thisHost, p-d+1)) && (matchIt || FoldedEQn(d, thisHost, p-d+1)))  {
  177.             return CONFIG_FALSECONDITION;
  178.             }
  179.         }
  180.         } else {
  181.         return CONFIG_BADENTRY;
  182.         }
  183.     } else  {
  184.         keybeg = text;
  185.         if (condition != NULL && conditionLength != NULL)  {
  186.         *condition = NULL;
  187.         *conditionLength = 0;
  188.         }
  189.     }
  190.  
  191.     /* Skip over leading white space */
  192.  
  193.     while (*keybeg && isspace(*keybeg))  {
  194.         keybeg++;
  195.     }
  196.  
  197.     if (*keybeg == '\0')  {
  198.         return CONFIG_EMPTYLINE;
  199.     }
  200.  
  201.     programBeg = keybeg;
  202.     programEnd = NULL;
  203.  
  204.     keyend = keybeg;
  205.  
  206.     /* Search for program name and key */
  207.  
  208.     if (program != NULL && programLength != NULL)  {
  209.         *program = NULL;
  210.         *programLength = 0;
  211.     }
  212.  
  213.     while (*keyend && *keyend != ':')  {
  214.         if (*keyend == '.' && programEnd == NULL)  {
  215.         /* Found program name - Null terminate string and move keybeg */
  216.  
  217.         if (keyend != programBeg)  {
  218.             programEnd = keyend-1;
  219.             while (programEnd != programBeg && isspace(*programEnd))  {
  220.             programEnd--;
  221.             }
  222.             programEnd++;
  223.         } else {
  224.             programEnd = programBeg;
  225.         }
  226.  
  227.         if (program != NULL && programLength != NULL)  {
  228.             *program = programBeg;
  229.             *programLength = programEnd - programBeg;
  230.         }
  231.  
  232.         /* Reset key beginning  and skip white space */
  233.  
  234.         keybeg = ++keyend;
  235.         while (*keybeg && isspace(*keybeg))  {
  236.             keybeg++;
  237.         }
  238.         keyend = keybeg;
  239.         } else  {
  240.         keyend++;
  241.         }
  242.     }
  243.  
  244.     if (*keyend == '\0' || keyend == keybeg)  {
  245.         return CONFIG_NOKEY;
  246.     }
  247.  
  248.     valpos = keyend + 1;
  249.  
  250.     /* strip off white space from key */
  251.  
  252.     keyend--;
  253.     while (keyend != keybeg && isspace(*keyend))  {
  254.         keyend--;
  255.     }
  256.  
  257.     keyend++;
  258.  
  259.     if (key != NULL && keyLength != NULL)  {
  260.         *key = keybeg;
  261.         *keyLength = keyend - keybeg;
  262.     }
  263.  
  264.     /* Strip off white space from value */
  265.  
  266.     while (*valpos != '\0' && isspace(*valpos))
  267.         valpos++;
  268.  
  269.     if (*valpos)  {
  270.         valend = &(valpos[strlen(valpos) - 1]);
  271.         while (valend != valpos && isspace(*valend))
  272.         valend--;
  273.  
  274.         /* save if there is any value associated with entry */
  275.  
  276.         valend++;
  277.  
  278.         if (value != NULL && valueLength != NULL)  {
  279.         *value = valpos;
  280.         *valueLength = valend - valpos;
  281.         }
  282.  
  283.         return CONFIG_FOUNDENTRY;
  284.     } else
  285.         return CONFIG_NOVALUE;
  286.  
  287.     } else {
  288.     return CONFIG_EOF;
  289.     }
  290. }
  291.  
  292. struct configurelist *ReadConfigureFile(fileName)
  293.     char *fileName;
  294. {
  295.     FILE *fp;
  296.  
  297.     errno = 0;
  298.     fp = fopen(fileName, "r");
  299.     if (fp) {
  300.     char mybuf[MAXCONFIGSIZE];
  301.     char *key;
  302.     char *program;
  303.     char *value;
  304.     int keyLength;
  305.     int programLength;
  306.     int valueLength;
  307.     struct configurelist *newItem;
  308.     struct configurelist *conHead = NULL;
  309.     struct configurelist *conEnd = NULL;
  310.     int retVal;
  311.  
  312.     while ((retVal = ReadConfigureLine(fp, mybuf, MAXCONFIGSIZE, &program, &programLength, &key, &keyLength, &value, &valueLength, NULL, NULL)) != CONFIG_EOF) {
  313.         if (retVal == CONFIG_FOUNDENTRY)  {
  314.         newItem = (struct configurelist *) malloc(sizeof(struct configurelist));
  315.         if (newItem == NULL)  {
  316.             fclose(fp); return NULL;
  317.         }
  318.         if ((newItem->key = (char *) malloc(keyLength + 1)) == NULL || (newItem->value = (char *) malloc(valueLength + 1)) == NULL)  {
  319.             fclose(fp); return NULL;
  320.         }
  321.         strncpy(newItem->key, key, keyLength);
  322.         newItem->key[keyLength] = '\0';
  323.         strncpy(newItem->value, value, valueLength);
  324.         newItem->value[valueLength] = '\0';
  325.         if (program != NULL && programLength != 0 && *program != '*')  {
  326.             if ((newItem->programName = (char *) malloc(programLength + 1)) == NULL)  {
  327.             fclose(fp); return NULL;
  328.             }
  329.             strncpy(newItem->programName, program, programLength);
  330.             newItem->programName[programLength] = '\0';
  331.         } else {
  332.             newItem->programName = NULL;
  333.         }
  334.         if (conHead == NULL)  {
  335.             conHead = newItem;
  336.         } else {
  337.             conEnd->next = newItem;
  338.         }
  339.         newItem->next = NULL;
  340.         conEnd = newItem;
  341.         }
  342.     }
  343.  
  344.     fclose(fp);
  345.  
  346.     return conHead;
  347.     }
  348.     return NULL;
  349. }
  350.     
  351.  
  352. char *GetConfig(header, key, usedefault)
  353.     struct configurelist *header;
  354.     char *key;
  355.     int usedefault;
  356. {
  357.     struct configurelist *p;
  358.     char *t;
  359.     char *testName;
  360.     char pName[500];
  361.  
  362.     if (header == NULL || key == NULL || *key == '\0')
  363.         return NULL;
  364.     
  365.     t = (char *) index(key, '.');
  366.  
  367.     if (t != NULL)  {
  368.     strncpy(pName, key, t - key);
  369.     pName[t-key] = '\0';
  370.     key = t + 1;
  371.     testName = pName;
  372.     } else {
  373.     testName = ProgramName;
  374.     }
  375.  
  376.     for (p = header; p != NULL; p = p->next) {
  377.     if (FoldedEQ(p->key, key) && ((usedefault && p->programName == NULL) || (p->programName != NULL && FoldedEQ(p->programName, testName))))  {
  378.         return (p->value);
  379.     }
  380.     }
  381.     return NULL;
  382. }
  383.  
  384. char *GetConfiguration(key)
  385. char *key;
  386. {
  387.     static int inited = 0;
  388.     static struct configurelist *setupHead = NULL;
  389.  
  390.     if (! inited) {
  391.     int i;
  392.  
  393.     for (i= 0; conf_ConfigNames[i]; ++i) {
  394.         setupHead = ReadConfigureFile(conf_ConfigNames[i]);
  395.         if (setupHead != NULL || errno == 0)
  396.         break;    /* setupHead will be NULL and errno be 0 if we
  397.                 could fopen() the file but not malloc() enough space
  398.                 to hold its contents. */
  399.     }
  400.     conf_ConfigErrno = errno;
  401.     inited = 1;
  402.     conf_ConfigUsed = i;
  403.     }
  404.     if (setupHead == NULL) {errno = conf_ConfigErrno; return NULL;}
  405.  
  406.     errno = 0;
  407.     return GetConfig(setupHead, key, 1);
  408. }
  409.  
  410. FreeConfigureList(cList)
  411.     register struct configurelist *cList;
  412. {
  413.     register struct configurelist *t;
  414.  
  415.     while (cList != NULL)  {
  416.     t = cList;
  417.     cList = t->next;
  418.     if (t->programName != NULL)
  419.         free(t->programName);
  420.     if (t->key != NULL)
  421.         free(t->key);
  422.     if (t->value != NULL)
  423.         free(t->value);
  424.     free(t);
  425.     }
  426. }
  427.  
  428. /* This is the main routine used to test the routine above */
  429.  
  430. #ifdef TESTINGONLYTESTING
  431. main(argc, argv)
  432. int argc;
  433. char **argv;
  434. {
  435.     int i;
  436.     char *val;
  437.     struct configurelist *ch = NULL;
  438.     char *ConfFile = NULL;
  439.  
  440.     for (i = 1; i < argc; i++)  {
  441.     if (argv[i][0] == '-')  {
  442.         if (argv[i][1] == 'f')  {
  443.         ConfFile = &(argv[i][2]);
  444.         ch = ReadConfigureFile(ConfFile);
  445.         if (ch == NULL) {
  446.             printf("Cannot read specified file ``%s'': errno %d", ConfFile, errno);
  447.             if (errno == 0) printf("; probably not a configuration file");
  448.             else if (errno == ENOENT) printf(" (no such file)");
  449.             else if (errno == EACCES) printf(" (permission denied)");
  450.             printf("\n");
  451.             ConfFile = NULL;
  452.         }
  453.         } else if (argv[i][1] == 'p') {
  454.         strcpy(ProgramName,&(argv[i][2]));
  455.         }
  456.     } else {
  457.         if (ch == NULL)  {
  458.         val = GetConfiguration(argv[i]);
  459.         } else {
  460.         val = GetConfig(ch, argv[i], 1);
  461.         }
  462.         printf("Configuration info for '%s' is '%s'\n", argv[i], (val == NULL ? "NULL" : val));
  463.     }
  464.     }
  465.     if (ConfFile == NULL) {
  466.     if (conf_ConfigUsed >= 0 && conf_ConfigNames[conf_ConfigUsed] != 0) {
  467.         printf("(Values were read from setup file %d, named ``%s''.)\n", conf_ConfigUsed, conf_ConfigNames[conf_ConfigUsed]);
  468.     } else {
  469.         if (conf_ConfigUsed >= 0) {
  470.         printf("No setup file could be found (resulting index was %d; errno %d).\nThe path used was:\n", conf_ConfigUsed, conf_ConfigErrno);
  471.         } else {
  472.         printf("No setup file search performed.  Setup file search path is:\n");
  473.         }
  474.         for (i = 0; conf_ConfigNames[i]; ++i) printf(" [%d]\t%s\n", i, conf_ConfigNames[i]);
  475.     }
  476.     } else {
  477.     printf("(Values were read from configuration file ``%s''.\n", ConfFile);
  478.     }
  479. }
  480. #endif /* TESTINGONLYTESTING */
  481.